package com.umeox.watch.moto.pedometer.data;


import static com.umeox.watch.moto.pedometer.base.PedometerDeviceEvent.Action.BOOT;
import static com.umeox.watch.moto.pedometer.base.PedometerDeviceEvent.Action.RESET;
import static com.umeox.watch.moto.pedometer.base.PedometerDeviceEvent.Action.SHUTDOWN;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;

import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.DateUtils;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.pedometer.base.BaseApp;
import com.umeox.watch.moto.pedometer.base.PedometerDeviceEvent;
import com.umeox.watch.moto.pedometer.base.QuranChallenge;
import com.umeox.watch.moto.pedometer.base.TodayChallenge;
import com.umeox.watch.moto.pedometer.util.CacheImpl;
import com.umeox.watch.moto.pedometer.util.ICache;
import com.umeox.watch.moto.pedometer.util.LogUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.concurrent.CopyOnWriteArrayList;


public class PedometerPresenter implements PedometerContract.Presenter {
    private static final String TAG = "PedometerData";
    private static final int MSG_SAVE_STEP = 1;
    private static final int MSG_UPLOAD_STEP = 2;
    private static final int MSG_SPORT_CHALLENGE_CHANGED = 3;
    private static final int MSG_QURAN_CHALLENGE_CHANGED = 4;

    private PedometerContract.View mView;
    private PedometerDataSource mPedometerData;
    private Handler mHandler = new Handler();
    private boolean mAlreadyLoaded;
    private final Handler handler;

    public PedometerPresenter(PedometerContract.View view) {
        mView = view;
        //20211209之前用的sensor监听，之后改为节点读取
        mPedometerData = new PedometerNodeData(this);
        HandlerThread handlerThread = new HandlerThread("PedometerData_thread");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper(), handlerCallback);
    }

    /**
     * 初始化计步数据监听并获取计步数据
     */
    @Override
    public void start() {
        Log.d(TAG, "ThemeF start: ");

        if (mAlreadyLoaded) {
            return;
        }
        handler.sendEmptyMessage(MSG_SPORT_CHALLENGE_CHANGED);
        handler.sendEmptyMessage(MSG_QURAN_CHALLENGE_CHANGED);
        mAlreadyLoaded = true;
        mPedometerData.load();

        mHandler.postDelayed(this::loadData, 2000);
    }

    /**
     * 获取计步数据
     */
    public void loadData() {
        mPedometerData.load();
        mHandler.postDelayed(this::loadData, 2000);
    }


    private ContentObserver mStepInfoObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            Logger.e("mStepInfoObserver onChange");
            mHandler.post(() -> mView.onHolderInfoChange());
            mHandler.post(PedometerPresenter.this::initPetInfo);

        }
    };
    final CopyOnWriteArrayList<TodayChallenge> mTodayChallenges = new CopyOnWriteArrayList<>();
    private ContentObserver mChallengeObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            handler.sendEmptyMessage(MSG_SPORT_CHALLENGE_CHANGED);
        }
    };

    final CopyOnWriteArrayList<QuranChallenge> mQuranChallenges = new CopyOnWriteArrayList<>();
    private ContentObserver mQuranLearnObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            handler.sendEmptyMessage(MSG_QURAN_CHALLENGE_CHANGED);
        }
    };


    private void getTodayChallenge() {
        mTodayChallenges.clear();
        Cursor _cursor = BaseApp.getAppContext().getContentResolver().query(DataProvider.SportsChallengeProvider.getUri(), null, null, null, null);
        if (_cursor == null) return;
        try {
            final int _cursorIndexOfId = getColumnIndexOrThrow(_cursor, "id");
            final int _cursorIndexOfSportType = getColumnIndexOrThrow(_cursor, "sportType");
            final int _cursorIndexOfDuration = getColumnIndexOrThrow(_cursor, "duration");
            final int _cursorIndexOfReminderTime = getColumnIndexOrThrow(_cursor, "reminderTime");
            final int _cursorIndexOfRewardValue = getColumnIndexOrThrow(_cursor, "rewardValue");
            final int _cursorIndexOfIsReminder = getColumnIndexOrThrow(_cursor, "isReminder");

            while (_cursor.moveToNext()) {
                final TodayChallenge _item;
                _item = new TodayChallenge();
                _item.id = _cursor.getLong(_cursorIndexOfId);
                _item.sportType = _cursor.getInt(_cursorIndexOfSportType);
                _item.duration = _cursor.getInt(_cursorIndexOfDuration);
                if (_cursor.isNull(_cursorIndexOfReminderTime)) {
                    _item.reminderTime = null;
                } else {
                    _item.reminderTime = _cursor.getString(_cursorIndexOfReminderTime);
                }
                _item.rewardValue = _cursor.getInt(_cursorIndexOfRewardValue);
                _item.isReminder = _cursor.getInt(_cursorIndexOfIsReminder);
                mTodayChallenges.add(_item);
            }

        } finally {

            _cursor.close();

        }
    }

    private void getQuranChallenge() {
        mQuranChallenges.clear();
        Cursor _cursor = BaseApp.getAppContext().getContentResolver().query(DataProvider.QuranLearnProvider.getUri(), null, null, null, null);
        if (_cursor == null) return;
        try {
            while (_cursor.moveToNext()) {
                final QuranChallenge _item;
                _item = new QuranChallenge();
                _item.id = _cursor.getInt(getColumnIndexOrThrow(_cursor,DataProvider.QuranLearnProvider.ID));
                _item.chapterIndex = _cursor.getInt(getColumnIndexOrThrow(_cursor, DataProvider.QuranLearnProvider.CHAPTER_INDEX));
                _item.duration = _cursor.getInt(getColumnIndexOrThrow(_cursor, DataProvider.QuranLearnProvider.DURATION));
                _item.deadline = _cursor.getString(getColumnIndexOrThrow(_cursor, DataProvider.QuranLearnProvider.DEADLINE));
                _item.rewardValue = _cursor.getInt(getColumnIndexOrThrow(_cursor, DataProvider.QuranLearnProvider.REWARD_VALUE));
                mQuranChallenges.add(_item);
            }

        } finally {
            _cursor.close();

        }
    }

    private int getColumnIndexOrThrow(Cursor cursor, String id) {
        return cursor.getColumnIndex(id);
    }

    private final ContentObserver mDistanceUnitObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            mHandler.post(() -> mView.onDistanceUnitChange());
        }
    };

    private void initPetInfo() {
        int target = DataProvider.getPlanValue(5000);
        mView.onStepInfoChange(target == 0 ? 5000 : target);
    }

    /**
     * 取消计步数据监听
     *
     * @param context
     */

    @Override
    public void stop(Context context) {
        Log.w(TAG, "stop: " + context);
        if (context == null) {
            return;
        }
        mAlreadyLoaded = false;
        mHandler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onStepCountChange(int stepCounts) {
        mView.onStepCountChange(stepCounts);
    }

    @Override
    public void getStepInfo() {
        initPetInfo();
        mPedometerData.getStepInfo();

    }

    private Handler.Callback handlerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Log.d(TAG, "handleMessage: " + msg.what);
            switch (msg.what) {
                case MSG_SAVE_STEP:
                    mPedometerData.saveStepCount();
                    break;
                case MSG_UPLOAD_STEP:
                    mPedometerData.uploadStepCount();
                    break;
                case MSG_SPORT_CHALLENGE_CHANGED:
                    getTodayChallenge();
                    mHandler.post(() -> mView.onSportChallengeChange(mTodayChallenges));
                    break;

                case MSG_QURAN_CHALLENGE_CHANGED:
                    getQuranChallenge();
                    mHandler.post(() -> mView.onQuranChallengeChange(mQuranChallenges));
                    break;
            }
            return false;
        }
    };


    @Override
    public void uploadSteps(int todayStepCount) {
        handler.sendEmptyMessage(MSG_UPLOAD_STEP);

    }

    @Override
    public void saveSteps() {
        handler.sendEmptyMessage(MSG_SAVE_STEP);

    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onPedometerDeviceEvent(PedometerDeviceEvent event) {

        final int action = event.mAction;
        final int todayMillis = DateUtils.getTodayMillis();
        switch (action) {
            case BOOT:
                Logger.e(TAG, "BOOT resetAndSaveStepCount");
                mPedometerData.resetAndSaveStepCount(todayMillis, todayMillis);
                break;
            case SHUTDOWN:
                Logger.e(TAG, "SHUTDOWN saveTotalStepCount");
                LogUtils.saveLog("-->SHUTDOWN saveTotalStepCount");
                mPedometerData.saveTotalStepCount();
                break;
            case RESET:
                Logger.e(TAG, "RESET resetSensorFlag");
                LogUtils.saveLog("-->RESET resetSensorFlag");
                int cacheTime = CacheImpl.getInstance().get(ICache.KEY_STEP_TIME, 0);
                mPedometerData.resetAndSaveStepCount(todayMillis, cacheTime);
                break;
        }
    }

    @Override
    public void onCreate() {
        DataProvider.HolderInfoProvider.registerContentObserver(false, mStepInfoObserver);
        DataProvider.SettingsProvider.registerContentObserver(false, mDistanceUnitObserver);
        DataProvider.SportsChallengeProvider.registerContentObserver(false, mChallengeObserver);
        DataProvider.QuranLearnProvider.registerContentObserver(false, mQuranLearnObserver);
        mPedometerData.onCreate();
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        final ContentResolver contentResolver = BaseApp.getAppContext().getContentResolver();
        contentResolver.unregisterContentObserver(mStepInfoObserver);
        contentResolver.unregisterContentObserver(mDistanceUnitObserver);
        contentResolver.unregisterContentObserver(mChallengeObserver);
        contentResolver.unregisterContentObserver(mQuranLearnObserver);
        mPedometerData.onDestroy();
    }


}
